Creating a Simple SOCKS5 Server and Client in C
In this tutorial, we will create a simple SOCKS5 server and client in C. The server will listen for incoming connections on a specified port, and the client will connect to the server, send a message, and receive a response. This tutorial is aimed at beginners, so we will explain each line of code in detail.
SOCKS5 Server Code
// socks5_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 1080
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char *hello = "Hello from SOCKS5 server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 1080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
close(server_fd);
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Forcefully attaching socket to the port 1080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
perror("listen");
close(server_fd);
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
close(server_fd);
exit(EXIT_FAILURE);
}
read(new_socket, buffer, 1024);
printf("Message from client: %s\n", buffer);
send(new_socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
close(new_socket);
close(server_fd);
return 0;
}
Let's break down the server code:
#include <stdio.h>
: Includes the standard input/output library.#include <stdlib.h>
: Includes the standard library for memory allocation, process control, conversions, etc.#include <string.h>
: Includes the string handling library.#include <unistd.h>
: Includes the POSIX operating system API.#include <arpa/inet.h>
: Includes definitions for internet operations.#define PORT 1080
: Defines the port number the server will listen on.int main()
: The main function where the program execution begins.int server_fd, new_socket;
: Declares file descriptors for the server and new socket.struct sockaddr_in address;
: Declares a structure to hold the server address.int opt = 1;
: Option for setsockopt to reuse the address and port.int addrlen = sizeof(address);
: Length of the address structure.char buffer[1024] = {0};
: Buffer to store the message from the client.const char *hello = "Hello from SOCKS5 server";
: Message to send to the client.if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
: Creates a socket and checks for errors.if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)))
: Sets socket options to reuse the address and port.address.sin_family = AF_INET;
: Sets the address family to IPv4.address.sin_addr.s_addr = INADDR_ANY;
: Binds the socket to all available interfaces.address.sin_port = htons(PORT);
: Sets the port number, converting it to network byte order.if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0)
: Binds the socket to the specified address and port.if (listen(server_fd, 3) < 0)
: Listens for incoming connections with a backlog of 3.if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0)
: Accepts an incoming connection.read(new_socket, buffer, 1024);
: Reads the message from the client into the buffer.printf("Message from client: %s\n", buffer);
: Prints the message from the client.send(new_socket, hello, strlen(hello), 0);
: Sends the hello message to the client.printf("Hello message sent\n");
: Prints a confirmation message.close(new_socket);
: Closes the new socket.close(server_fd);
: Closes the server socket.return 0;
: Exits the program.
SOCKS5 Client Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 1080
int main() {
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from SOCKS5 client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
valread = read(sock, buffer, 1024);
printf("%s\n", buffer);
return 0;
}
Let's break down the client code:
#include <stdio.h>
: Includes the standard input/output library.#include <stdlib.h>
: Includes the standard library for memory allocation, process control, conversions, etc.#include <string.h>
: Includes the string handling library.#include <unistd.h>
: Includes the POSIX operating system API.#include <arpa/inet.h>
: Includes definitions for internet operations.#define PORT 1080
: Defines the port number the client will connect to.int main()
: The main function where the program execution begins.int sock = 0, valread;
: Declares a socket and a variable to store the number of bytes read.struct sockaddr_in serv_addr;
: Declares a structure to hold the server address.char *hello = "Hello from SOCKS5 client";
: Message to send to the server.char buffer[1024] = {0};
: Buffer to store the message from the server.if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
: Creates a socket and checks for errors.serv_addr.sin_family = AF_INET;
: Sets the address family to IPv4.serv_addr.sin_port = htons(PORT);
: Sets the port number, converting it to network byte order.if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
: Converts the IP address from text to binary form and checks for errors.if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
: Connects to the server and checks for errors.send(sock, hello, strlen(hello), 0);
: Sends the hello message to the server.printf("Hello message sent\n");
: Prints a confirmation message.valread = read(sock, buffer, 1024);
: Reads the message from the server into the buffer.printf("%s\n", buffer);
: Prints the message from the server.return 0;
: Exits the program.
Compiling and Running the Code
To compile and run the provided C source code files for the ARM64 architecture, follow these steps:
# Compile the server code
gcc -o socks5_server socks5_server.c
# Compile the client code
gcc -o socks5_client socks5_client.c
# Run the server
./socks5_server
# Run the client in a separate terminal
./socks5_client
This will start the SOCKS5 server, which listens on port 1080, and the client will connect to the server, send a message, and receive a response.
Check out some other Bands on Bandcamp.com. Crazy Fingers (Vancouver 1991), Flying Butt Pliers, and Hammy Ham Hands.
Proudly powered by a Text Editor, an Sftp client and some Internet Searches.
2024 dispelled.ca end of file.